<?php
// $Id:

/**
 * @file
 *
 * Nouveau parser etendu du parser FeedsXPathParserXML
 */


class TfFeedsXPathParserXML extends FeedsXPathParserXML {
  /**
  * Override parent::getMappingSources().
  */
  public function getMappingSources() {
    $mappings = $this->filterMappings(feeds_importer($this->id)->processor->config['mappings']);
    $next = 0;
    if (!empty($mappings)) {
      $last_mapping = end(array_keys($mappings));
      $next = explode(':', $last_mapping);
      $next = $next[1] + 1;
    }
    return array(
      'tf_xpathparser:' . $next => array(
        'name' => t('XPath Expression (tf)'),
        'description' => t('Allows you to configure an XPath expression that will populate this entity.'),
      ),
    ) + parent::getMappingSources();
  }

  /**
   * Filters mappings, returning the ones that belong to us.
   */
  private function filterMappings($mappings) {
    $our_mappings = array();
    foreach ($mappings as $mapping) {
      if (strpos($mapping['source'], 'tf_xpathparser:') === 0) {
        $our_mappings[$mapping['source']] = $mapping['target'];
      }
    }
    return $our_mappings;
  }
  
  /**
   * Define defaults.
   */
  public function configDefaults() {
    $default_keys = parent::configDefaults();

    // On ajoute une variable dans laquelle on pourra stocker des données
    // lors de la soumission du formulaire de configuration du processor
    $default_keys['tf_sources'] = array();
    //$default_keys['tf_field_collection_item_sources'] = array();
    return $default_keys;
  }


  /**
   * Source form.
   */
  public function sourceForm($source_config) {
    $form = parent::sourceForm($source_config);

    $mappings_ = feeds_importer($this->id)->processor->config['mappings'];
    $targets = feeds_importer($this->id)->processor->getMappingTargets();
    if (empty($source_config)) {
      $source_config = $this->config;
    }

    $mappings = array();
    foreach ($mappings_ as $mapping) {
      if (strpos($mapping['source'], 'tf_xpathparser:') === 0) {
        $mappings[$mapping['source']] = $mapping['target'];
      }
    }

    if (empty($mappings)) {
      return $form;
    }

    $form['xpath']['tf_sources'] = array(
      '#type' => 'fieldset',
      '#tree' => TRUE,
      '#title' => t('XPath Parser Settings (entity)'),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
    );

    foreach ($mappings as $source => $target_key) {
      $target = $targets[$target_key];
      $target_instance = $target['field_info'];
      $target_fields = $target_instance['fields'];

      if (isset($target['entity']) && $target['entity']) {
        $form['xpath']['tf_sources'][$source]['entity'] = array(
          '#type' => 'textfield',
          '#title' => $source . " (" . $target_key . ")",
          '#description' => t('Ecrire la requete XPath query qui retrouvera les entites du contenu.'),
          '#default_value' => isset($source_config['tf_sources'][$source]['entity']) ? $source_config['tf_sources'][$source]['entity'] : '',
          '#maxlength' => 1024,
          '#size' => 80,
        );

        $form['xpath']['tf_sources'][$source]['fields'] = array(
          '#type' => 'fieldset',
          '#tree' => TRUE,
          '#title' => t('Fields'),
          '#collapsible' => TRUE,
          '#collapsed' => TRUE,
        );
        foreach ($target_fields as $key_field) {
          $form['xpath']['tf_sources'][$source]['fields'][$key_field] = array(
            '#type' => 'textfield',
            '#title' => $key_field,
            '#default_value' => isset($source_config['tf_sources'][$source]['fields'][$key_field]) ? $source_config['tf_sources'][$source]['fields'][$key_field] : '',
            '#description' => 'Ecrire la requete XPATH pour retourver un champ de l\'entite.'
          );
        }

      }
    }
    return $form;
  }


/**
   * Starts the parsing. First runs the context query, then queries each
   * item from the context with the field queries.
   *
   * @param $xml
   *   A SimpleXMLElement object.
   *
   * @return array
   *   Returns a structured array suitable for use in FeedsParserResult().
   */
  protected function query($xml) {
    $parsed_items = parent::query($xml);

    $all_items = $xml->xpath($this->source_config['context']);

    foreach ($all_items as $item_key => $item) {
      $parsed_item = array();
      foreach ($this->source_config['tf_sources'] as $source => $element) {
        $xpath = $element['entity'];
        $fields = $element['fields'];
        $result = $this->query_entities($item, $source, $xpath, $fields);
        $parsed_item[$source] = $result;
      }
      $parsed_items[$item_key] += $parsed_item;
    }

    return $parsed_items;
  }

  /**
   *
   * @param <type> $item
   * @param <type> $source
   * @param <type> $query
   * @return <type> 
   */
  private function query_entities($item, $source, $query, $fields) {
    // On retrouve les entites de l'item
    $entities = $item->xpath($query);
    $parsed_items = array();
    
    foreach ($entities as $entity) {
      $parsed_item = array();
      foreach ($fields as $field_key => $xpath) {
        $result = $this->parseSourceElement($entity, $xpath, $source);
        $parsed_item[$field_key] = $result;
      }
      $parsed_items[] = $parsed_item;
    }

    return $parsed_items;
  }

}
